package com.jreque.executor;

import com.jreque.persistance.IQueuePersistance;
import com.jreque.persistance.QueuePersistanceFactory;
import com.jreque.queue.QueueManager;
import com.jreque.queue.Task;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

/**
 * Entry-point class that executes tasks from queue in loop.
 */
public class QueueExecutor extends Thread {
    private static final int WAIT_TIME = 1000;
    
    static QueueManager executor;
    /**
     * Returns the shared instance of QueueManager. Used for debugging
     * @return the executor
     */
    public static QueueManager getExecutor() {
        return executor;
    }
    /**
     * Entry-point method - reads properies file name and names of queues to execute
     * @param args 
     */
    public static void main(java.lang.String[] args) {
        boolean first = true;
        for(String qn : args) {
            if(first) {
                first = false;
                File propFile = new File(qn);
                if(!propFile.exists()) {
                    System.err.println("File: " + qn + " not found");
                    System.exit(1);
                }
                if(!propFile.canRead()) {
                    System.err.println("Could not read file: " + qn);
                    System.exit(1);
                }
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream(propFile);
                } catch (FileNotFoundException ex) {}
                Properties p = new Properties();
                try {
                    p.load(fis);
                } catch (IOException ex) {
                    System.err.println("Error reading file: " + qn);
                    System.exit(1);
                }
                IQueuePersistance persistance = null;
                try {
                    persistance = QueuePersistanceFactory.getInstanceForProperties(p);
                } catch (ClassNotFoundException ex) {
                    System.err.println("Wrong persistance class specified");
                    System.err.println(ex.getMessage());
                    System.exit(1);
                } catch (Exception ex) {
                    System.err.println("Error initializing the persistance layer");
                    System.exit(1);
                }
                executor = new QueueManager(persistance);
            } else {
                QueueExecutor qe = new QueueExecutor(qn);
                qe.setDaemon(false);
                qe.start();
            }
        }
    }

    /**
     * The name of the queue executed by this instance
     */
    private String queueName;

    public QueueExecutor(String queueName) {
        this.queueName = queueName;
    }

    /**
     * Dequeues tasks from the queue and executes them
     */
    public void run() {
        while(!isInterrupted()) {
            int timeout = executor.getTimeout(queueName);
            Task t = executor.dequeueTask(queueName, timeout);
            if(t != null) {
                t.invoke();              
                executor.completeTask(t);
            } else {
                try {
                    Thread.sleep(WAIT_TIME);
                } catch (InterruptedException ex) {
                    System.err.println("Executor for queue: " + queueName + " interrupted.");
                }
            }
        }
    }
}

